import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.text.*;

import java.awt.Color;



public class Fenetre extends JFrame implements ActionListener,FocusListener{	

	public static JFrame frame;
	public static JButton lancer,arreter,vider;
	public JTextField taillePop_Champs,nbGeneration_Champs, tauxCrois_Champs,tauxMuta_Champs;

	public double  cercle_A ;
	public double  cercle_B ;
	public double  cercle_C ;
	public static int nbGene,taillePop;
	public static float tauxC,tauxM;


	public static JProgressBar progressBar;
	public static boolean running = false;
	public static JTextArea infoArea;
	public static JTable tableau_resultat;
	public static String[] entetes = {"Test", "Taux Croisement","Taux Mutation", "Taille Population","Nbre Generation","ID Best","Fitnesse Best","Fitnesse Moyenne"};
	public static Object[][] donnees;
	public static int Numtest = 1;



	private final String CROISEMENT = "Taux de croisement ?", 
			MUTATION = "Taux de mutation ?",
			GENERATION = "Nombre de generations ?",
			POPULATION = "Taille de population ?";

	public static JPanel rightPanel2;
	public static JPanel panel;
	public static JPanel centerPanel;
	public static JPanel rightPanel;
	public static JPanel rightPanel1;
	public static  JPanel bottomPanel;
	// constructeur de la classe Fenetre
	public Fenetre () {

		this.setTitle("Algorithmes Genethique - Probleme de cercle");
		this.setSize(920,700);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.setResizable(false);
		//Container c=this.getContentPane();
		this.setContentPane(contentPane());
		this.getRootPane().setDefaultButton(lancer);
		this.repaint();
		this.setLocation(new Point(4,4));
		this.progressBar.setMaximum(nbGene);
	}

	private JPanel contentPane() {

		panel = new JPanel(new BorderLayout());
		panel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));

		centerPanel = new JPanel(new BorderLayout());
		centerPanel.setSize(100, 200);

		rightPanel = new JPanel(new BorderLayout());
		rightPanel.setSize(500, 200);
		rightPanel.setPreferredSize(new Dimension(500,200));

		rightPanel1 = new JPanel(new GridBagLayout());
		rightPanel1.setPreferredSize(new Dimension(100,100));
		rightPanel1.setBorder(BorderFactory.createLineBorder(Color.black));
		rightPanel1.setBackground(Color.orange);




		bottomPanel = new JPanel(new BorderLayout());
		bottomPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
		bottomPanel.setPreferredSize(new Dimension(600,700));
		bottomPanel.setBackground(Color.pink);

		GridBagConstraints c = new GridBagConstraints ();
		JLabel croisementLabel = new JLabel(CROISEMENT);
		JLabel mutationLabel = new JLabel(MUTATION);
		JLabel generationLabel = new JLabel(GENERATION);
		JLabel populationLabel = new JLabel(POPULATION);

		progressBar = new JProgressBar();
		progressBar.setMinimum(0);
		progressBar.setStringPainted(true);

		infoArea = new JTextArea(8,8);
		infoArea.setLineWrap(true);

		JScrollPane scroll = new JScrollPane(infoArea);
		scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		scroll.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
		scroll.setPreferredSize(new Dimension(600,650));



		taillePop_Champs = new JTextField(15);
		taillePop_Champs.addFocusListener((FocusListener) this);

		nbGeneration_Champs = new JTextField(15);
		nbGeneration_Champs.addFocusListener((FocusListener) this);

		tauxCrois_Champs = new JTextField(15);
		tauxCrois_Champs.addFocusListener((FocusListener) this);

		tauxMuta_Champs = new JTextField(15);
		tauxMuta_Champs.addFocusListener((FocusListener) this);

		lancer = new JButton(new ImageIcon(getClass().getResource("/play.png")));
		lancer.addActionListener(this);

		arreter = new JButton(new ImageIcon(getClass().getResource("/stop.png")));
		arreter.addActionListener(this);

		vider = new JButton("vider le tableau");
		vider.addActionListener(this);

		rightPanel.add(rightPanel1);
		panel.add(rightPanel, BorderLayout.EAST);


		c.anchor = GridBagConstraints.NORTH;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 0;
		c.gridwidth = 2; 
		c.insets = new Insets(0,120,5,120);
		c.weightx = 1;

		rightPanel1.add(populationLabel,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 3;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(taillePop_Champs,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 4;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(generationLabel,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 5;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(nbGeneration_Champs,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 6;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(croisementLabel,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 7;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(tauxCrois_Champs,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 8;
		c.gridwidth = 2;  
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(mutationLabel,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 9;
		c.gridwidth = 2; 
		c.insets = new Insets(0,120,5,120);
		rightPanel1.add(tauxMuta_Champs,c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 10;
		c.gridwidth = 1;  
		c.insets = new Insets(20,120,5,260);
		c.weightx = 2;

		rightPanel1.add(lancer,c);

		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		c.gridy = 10;
		c.gridwidth = 1;  
		c.insets = new Insets(20,270,0,120);
		c.weightx = 2;

		rightPanel1.add(arreter,c);
		panel.add(bottomPanel, BorderLayout.WEST);

		donnees = new Object[10][8];
		tableau_resultat = new JTable(donnees, entetes);




		float[] hsb=new float[3];
		Color.RGBtoHSB(164,255, 46, hsb);	 
		tableau_resultat.setBackground(Color.getHSBColor(hsb[0], hsb[1],hsb[2]));
		tableau_resultat.setRowHeight(25);

		bottomPanel.add(new JScrollPane(tableau_resultat), BorderLayout.NORTH);
		bottomPanel.add(infoArea,BorderLayout.CENTER);
		bottomPanel.add(progressBar, BorderLayout.SOUTH);
		
		bottomPanel.add(progressBar, BorderLayout.AFTER_LINE_ENDS);
	    bottomPanel.add(vider,BorderLayout.PAGE_END);

		return panel;
	}


	public void actionPerformed(ActionEvent e)
	{
		Object src = e.getSource();

		if(src == lancer) {
			if ((!running) && conditions()) {

				Individual bestSolution = null;	
				


				Algorithm.setUniformRate(tauxC);
				Algorithm.setMutationRate(tauxM);
				Population myPop = new Population(taillePop, true);
				
				
				int generationCount = 0;
		        while (generationCount < myPop.getNbIteration()) {
		            generationCount++;
		            System.out.println("Generation: " + generationCount + " Fittest: " + myPop.getFittest().getFitness());
		            myPop = Algorithm.evolvePopulation(myPop);
		        }



				infoArea.setText("");
				
				infoArea.setText("Nouveau depart");
				infoArea.append(" \n Pourcentage pour les mutations: "+ tauxC);
				infoArea.append(" \n Pourcentage pour les croisement: "+ tauxM);
				infoArea.append(" \n La taille de la population: "+taillePop);
				infoArea.append(" \n Le nombre de generation: "+nbGene);
				infoArea.append("\n La meilleure valeur de fitness trouvee est : " + bestSolution.getFitness());
				progressBar.setMaximum(nbGene);
				progressBar.setValue(nbGene);
				remplir_Tableau_Resultat(Numtest, 1, myPop.getFittest().getFitness(), myPop.getFitnessAverage());
				Numtest++;
				rightPanel2 = new monCanvas(myPop.getIndividual(0).getD1(), myPop.getIndividual(0).getD2(), myPop.getIndividual(0).getD3());

				rightPanel2.setPreferredSize(new Dimension(300,420));
				rightPanel2.setBorder(BorderFactory.createLineBorder(Color.black));
				rightPanel.add(rightPanel2, BorderLayout.NORTH);

				lancer.setEnabled(false);
				running = true;
				this.repaint();
			}else {

				infoArea.setText("");
				infoArea.append(" Veuillez remplir tous les champs ...\n");


			}
		}else if (src == arreter){

			infoArea.setText("");
			infoArea.append(" Pour une nouvelle Generation \n Veuillez remplir tous les champs  ...\n");
			nbGene = 0;
			taillePop = 0;
			tauxC = (float)0.0;
			tauxM = (float)0.0;
			
			progressBar.setValue(nbGene);
			lancer.setEnabled(true);
			this.getRootPane().setDefaultButton(lancer);
			running = false;
			this.repaint();
		}else if (src == vider){
			
			
			for(int i = 0; i < 10; i++ )
			{
				donnees[i][0] = null;
				donnees[i][1] = null;
				donnees[i][2] = null;
				donnees[i][3] = null;
				donnees[i][4] = null;
				donnees[i][5] = null;
				donnees[i][6] = null;
				donnees[i][7] = null;
			}
			 this.tableau_resultat.addRowSelectionInterval(0,8);
			 Numtest = 1;
			 this.repaint();
			
		}
	}


	private boolean conditions() {

		boolean condition0 = false;
		boolean condition1 = false;
		boolean condition2 = false;
		boolean condition3 = false;
		try {
			tauxM = Float.parseFloat(tauxMuta_Champs.getText());
			condition0 = true;
		} catch (NumberFormatException f) {
			condition0 = false;
		}

		try {
			taillePop = Integer.parseInt(taillePop_Champs.getText());
			condition1 = true;
		} catch (NumberFormatException f) {
			condition1 = false;
		}
		try {
			nbGene = Integer.parseInt(nbGeneration_Champs.getText());
			condition2 = true;
		} catch (NumberFormatException f) {
			condition2 = false;
		}
		try {
			tauxC = Float.parseFloat(tauxCrois_Champs.getText());
			condition3 = true;
		} catch (NumberFormatException f) {
			condition3 = false;
		}

		return condition0 && condition1 && condition2 && condition3 ;

	}

	public void focusGained(FocusEvent e) {
		this.getRootPane().setDefaultButton(lancer);
		((JTextComponent) e.getSource()).selectAll();
	}

	public void focusLost(FocusEvent e) {
		((JTextComponent) e.getSource()).setCaretPosition(0);
	}


	public void remplir_Tableau_Resultat(int Numtest,int IDBest, double FitBest, double FitMoyenne){


		donnees[Numtest - 1][0] =  "N�:".concat(String.valueOf(Numtest));
		donnees[Numtest - 1][1] =  Float.toString(tauxC);
		donnees[Numtest - 1][2] =  Float.toString(tauxM);
		donnees[Numtest - 1][3] =  String.valueOf(taillePop);
		donnees[Numtest - 1][4] =  String.valueOf(nbGene);
		donnees[Numtest - 1][5] =  String.valueOf(IDBest);
		donnees[Numtest - 1][6] =  Double.toString(FitBest);
		donnees[Numtest - 1][7] =  Double.toString(FitMoyenne);



		this.tableau_resultat.addRowSelectionInterval(0,8); 


	}
}